<template>
  <div class="pic-preview" :style="containerStyle">
    <img :src="src" :alt="alt" class="preview-img" :style="imgStyle" />
    <div class="hover-mask" @click="handlePreview">
      <el-icon class="preview-icon" size="14">
        <View />
      </el-icon>
      <span class="ml4 color-white fs-12">{{ $t("预览") }}</span>
    </div>
  </div>

  <!-- 图片预览弹窗 -->
  <Teleport to="body">
    <div v-if="showPreview" class="preview-modal" @click="handleClose">
      <div class="operation-bar">
        <el-icon class="operation-icon" @click.stop="handleRotateLeft">
          <Refresh />
        </el-icon>
        <el-icon class="operation-icon" @click.stop="handleRotateRight">
          <RefreshRight />
        </el-icon>
        <el-icon class="operation-icon" @click.stop="handleZoomOut">
          <ZoomOut />
        </el-icon>
        <el-icon class="operation-icon" @click.stop="handleZoomIn">
          <ZoomIn />
        </el-icon>
        <el-icon class="operation-icon" @click="handleClose">
          <Close />
        </el-icon>
      </div>
      <div class="modal-content">
        <img 
          :src="src" 
          :alt="alt" 
          class="full-img" 
          :style="{
            transform: `rotate(${rotation}deg) scale(${scale})`,
            transition: 'transform 0.3s'
          }"
        />
      </div>
    </div>
  </Teleport>
</template>

<script setup>
import { ref, computed } from "vue";
import { View, Close, Refresh, RefreshRight, ZoomIn, ZoomOut } from "@element-plus/icons-vue";

const props = defineProps({
  // 图片源
  src: {
    type: String,
    required: true,
  },
  // 图片描述
  alt: {
    type: String,
    default: "",
  },
  // 容器宽度
  width: {
    type: [String, Number],
    default: "100px",
  },
  // 容器高度
  height: {
    type: [String, Number],
    default: "100px",
  },
  // 图片填充方式
  fit: {
    type: String,
    default: "fill",
    validator: (value) => {
      return ["fill", "contain", "cover", "none", "scale-down"].includes(value);
    },
  },
  // 预览弹窗宽度
  previewWidth: {
    type: String,
    default: "80%",
  },
});

// 预览弹窗显示状态
const showPreview = ref(false);

// 容器样式
const containerStyle = computed(() => {
  return {
    width: typeof props.width === "number" ? `${props.width}px` : props.width,
    height:
      typeof props.height === "number" ? `${props.height}px` : props.height,
  };
});

// 图片样式
const imgStyle = computed(() => {
  return {
    objectFit: props.fit,
  };
});

// 弹窗宽度
const dialogWidth = computed(() => props.previewWidth);

// 图片旋转角度
const rotation = ref(0);
// 图片缩放比例
const scale = ref(1);

// 向左旋转
const handleRotateLeft = () => {
  rotation.value = (rotation.value - 90) % 360;
};

// 向右旋转
const handleRotateRight = () => {
  rotation.value = (rotation.value + 90) % 360;
};

// 放大
const handleZoomIn = () => {
  if (scale.value < 3) { // 限制最大放大倍数
    scale.value = +(scale.value + 0.5).toFixed(1);
  }
};

// 缩小
const handleZoomOut = () => {
  if (scale.value > 0.5) { // 限制最小缩小倍数
    scale.value = +(scale.value - 0.5).toFixed(1);
  }
};

// 处理预览点击
const handlePreview = () => {
  showPreview.value = true;
  // 禁止body滚动
  document.body.style.overflow = 'hidden';
};

// 处理关闭
const handleClose = () => {
  showPreview.value = false;
  // 恢复body滚动
  document.body.style.overflow = '';
  // 重置旋转和缩放
  rotation.value = 0;
  scale.value = 1;
};
</script>

<style scoped lang="scss">
.pic-preview {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  user-select: none; // 禁止选中
  box-shadow: 0 0 2px #c4c4c480;
  &:hover {
    .hover-mask {
      display: flex;
    }
  }

  .preview-img {
    width: 100%;
    height: 100%;
    user-select: none; // 禁止选中
    -webkit-user-drag: none; // 禁止拖拽
  }

  .hover-mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    display: none;
    justify-content: center;
    align-items: center;
    transition: all 0.3s;

    .preview-icon {
      color: #fff;
      font-size: 24px;
      cursor: pointer;
    }
  }

  &:hover .hover-mask {
    opacity: 1;
  }
}

.preview-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 2000;
  display: flex;
  justify-content: center;
  align-items: center;
  user-select: none; // 禁止选中

  .operation-bar {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 2001;
    display: flex;
    gap: 20px;
    padding: 10px;
    border-radius: 4px;
    background-color: rgba(0, 0, 0, 0.3);
    user-select: none; // 禁止选中

    .operation-icon {
      color: #fff;
      font-size: 24px;
      cursor: pointer;
      transition: all 0.3s;
      user-select: none; // 禁止选中

      &:hover {
        transform: scale(1.2);
        opacity: 0.8;
      }
    }
  }

  .modal-content {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;

    .full-img {
      max-width: 90vw;
      max-height: 90vh;
      object-fit: contain;
      transform-origin: center center;
      user-select: none; // 禁止选中
      -webkit-user-drag: none; // 禁止拖拽
    }
  }
}
</style>
